package com.game;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.utils.Timer;
import com.badlogic.gdx.utils.Timer.Task;
import com.player.Data;
import com.player.Enemy;
import com.player.Player;
import com.world.World;

public class GameScreen implements Screen
{
	private TiledMap map;
	private World world;
	private OrthogonalTiledMapRenderer renderer; 
	private OrthographicCamera camera;
	private BitmapFont font;

	private float animateTime;
	private static boolean spawned;
	private Sprite capsule;
	private int capsuleY = -3;

	private Player player;
	private Enemy enemy;	
	private Start game;
	
	private int minutes;
	private int seconds;
	
	private Data data;
	
	public GameScreen(Start game, Player player) {
		this.game = game;
		
		world = new World();
		map = world.getMap();
		
		font = new BitmapFont();
		
		renderer = new OrthogonalTiledMapRenderer(map);
		camera = new OrthographicCamera();
		
		this.player = player;
		player.setGameScreen(this);
		
		player.getClient().setOwnHero(player.getHero());
		
		setPlayerPosition();
		
		enemy = new Enemy(player.getClient().getEnemyHero());
		
		player.getClient().setEnemy(enemy);
		
		if (player.getClient().getIndex() == 1) {
			enemy.setPosition(29 * 32, 4 * 32);
		} else {
			enemy.setPosition(1 * 32, 4 * 32);
		}
		
		spawnCapsule();
		
		Timer spawnCapsule = new Timer();  
		spawnCapsule.scheduleTask(new Task() {  
            @Override  
            public void run() {  
            	spawnCapsule();
            }  
        }, 60, 60);  
		
		Timer endGame = new Timer();  
		endGame.scheduleTask(new Task() {  
            @Override  
            public void run() {  
            	endGame();
            }  
        }, 60 * 3);
		
		Timer countTimer = new Timer();  
		countTimer.scheduleTask(new Task() {  
            @Override  
            public void run() { 
            	seconds++;
            	
            	if (seconds == 60) {
            		seconds = 0;
            		minutes++;
            	}
            }  
        }, 1, 1);
		
		data = new Data(player.getPosition(), player.getVelocity(), player.getElapsedAttack(), player.getElapsedQ(), 
				player.getElapsedW(), player.getElapsedE(), player.getFlipped(), player.getHeroToCastOn());
	}
	
	public void setPlayerPosition() {
		if (player.getClient().getIndex() == 1) {
			player.setPosition(1 * player.getCollisionLayer().getTileWidth(), 4 * player.getCollisionLayer().getTileHeight());
		} else {
			player.setPosition(29 * player.getCollisionLayer().getTileWidth(), 4 * player.getCollisionLayer().getTileHeight());
		}
	}
	
	@Override
	public void show() {		
		
	}
	
	@Override
	public void render(float delta) {				
		Gdx.gl.glClearColor(0, 0, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		
		animateCapsule();
		
		renderer.setView(camera);
		renderer.render();
		
		// Team Kill Statistiken anzeigen
		showTeamKills();
		
		// Zeit anzeigen
		showTime();
		
		// Zeichnen
		renderer.getSpriteBatch().begin();
		draw();
		renderer.getSpriteBatch().end();
		
		// Position an den Server schicken	
		sendData();
	}
	
	private void sendData() {
		data.setPosition(player.getPosition());
		data.setVelocity(player.getVelocity());
		data.setElapsedAttack(player.getElapsedAttack());
		data.setElapsedQ(player.getElapsedQ());
		data.setElapsedW(player.getElapsedW());
		data.setElapsedE(player.getElapsedE());
		data.setFlipped(player.getFlipped());
		data.setHeroToCastOn(player.getHeroToCastOn());
		
		player.getClient().send(data);		
	}

	private void draw() {
		// Spieler zeichnen
		player.draw(renderer.getSpriteBatch());
		
		// Kapsel zeichnen
		capsule.draw(renderer.getSpriteBatch());
		
		// Gegner zeichnen
		player.getEnemy().draw(renderer.getSpriteBatch());
	}

	private void showTeamKills() {
		if (player.getClient().getIndex() == 1) {
			font.setColor(1.0f, 1.0f, 1.0f, 1.0f);
			
			renderer.getSpriteBatch().begin();
			font.draw(renderer.getSpriteBatch(), String.valueOf(player.getMyTeamKills()) , 100, 700);
			font.draw(renderer.getSpriteBatch(), String.valueOf(player.getEnemyTeamKills()), 1024 - font.getBounds(String.valueOf(player.getEnemyTeamKills())).width - 100, 700);
			renderer.getSpriteBatch().end();
		} else {
			font.setColor(1.0f, 1.0f, 1.0f, 1.0f);
			
			renderer.getSpriteBatch().begin();
			font.draw(renderer.getSpriteBatch(), String.valueOf(player.getMyTeamKills()), 1024 - font.getBounds(String.valueOf(player.getEnemyTeamKills())).width - 100, 700);
			font.draw(renderer.getSpriteBatch(), String.valueOf(player.getEnemyTeamKills()) , 100, 700);
			renderer.getSpriteBatch().end();
		}
	}
	
	private void showTime() {
		String formattedSeconds = String.format("%02d", seconds);
		
		renderer.getSpriteBatch().begin();
		font.draw(renderer.getSpriteBatch(),  minutes + ":" + formattedSeconds, World.WIDTH / 2, 700);
		renderer.getSpriteBatch().end();
	}

	private void spawnCapsule() {											
		TextureAtlas atlas = new TextureAtlas("img/terrain/capsules/capsules.pack");			
			
		capsule = atlas.createSprite("disable");
		
		capsule.setAlpha(1);
		capsule.setX(18 * 32);
		capsule.setY(7 * 32 + 3);
		
		spawned = true;
	}
	
	private void animateCapsule() {
		float elapsed = (System.nanoTime() - animateTime) / 1000000000.0f;
		
		if (spawned) {
			if (elapsed > 1) {
				if (capsule != null) {
					capsuleY =  -capsuleY;
					animateTime = System.nanoTime();
					capsule.setY(capsule.getY() + capsuleY);
				}
			}
		} else {
			capsule.setAlpha(0);
		}
	}
	
	public void endGame() {
		if (player.getMyTeamKills() > player.getEnemyTeamKills()) {
			game.setScreen(new EndScreen(game, "Du hast gewonnen!"));
		} else if (player.getMyTeamKills() < player.getEnemyTeamKills()) {
			game.setScreen(new EndScreen(game, "Du hast verloren!"));
		} else {
			game.setScreen(new EndScreen(game, "Unentschieden!"));
		}

        dispose();
	}

	@Override
	public void resize(int width, int height) {
		camera.viewportHeight = height;
		camera.viewportWidth = width;
		 
		camera.setToOrtho(false, World.WIDTH, World.HEIGHT);
		camera.update();
	}

	@Override
	public void hide() {
		dispose();		
	}

	@Override
	public void pause() {
	}

	@Override
	public void resume() {
	}

	@Override
	public void dispose() {
		map.dispose();
	}
	
	public static boolean isSpawned() {
		return spawned;
	}
	
	public static void setSpawned(boolean spawn) {
		spawned = spawn;
	}
}
